/**
 * @author talent
 */
var AjaxRequest = function(url, options){
    this.url = url;
    this.options = {
        parameters: {},
        async: true,
        contentType:  'application/x-www-form-urlencoded',
        method: 'post',
        encoding:   'UTF-8',
        onexecute: function(){},
        onsuccess: function(){},
        onfailure: function(){},
        onerror: function(){}
    };
    this.Extend(options, this.options);
    this.options.method = this.options.method.toUpperCase();
    this.parameters = this.createQuery(this.options.parameters);
    if(!window.XMLHttpRequest && window.ActiveXObject){
     this.loader = function(){
       for(var i = 0, a = ['MSXML3', 'MSXML2', 'Microsoft']; i < a.length; i ++)
           try{
               return new ActiveXObject(a[i] + '.XMLHTTP');
           }catch(ex){}
     }();
    }else this.loader = new XMLHttpRequest();
    this.request.call(this);
}
AjaxRequest.prototype = {
    type: /(text|application)\/(x-)?(\S+)/i,
    Extend: function(source, dest){
        for(var key in source) dest[key] = source[key];
    },
    request: function(){
        var o = this.options, self = this;
        o.method == "POST" || o.method == "GET" || (o.method = "POST");
        if(o.method=='GET'&& self.parameters !== "")
            self.url = ((self.url.match(/\?/))?self.url:(self.url+"?"))+self.parameters;
        else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
            this.parameters += '&_=';
        try {
            o.onexecute();
            this.loader.open(o.method, this.url, o.async);
            this.loader.onreadystatechange = function(){
            self.onStateChange.call(self)
        };
        this.setHeader.call(this);
        this.sendBody = o.method == 'GET' ? null : this.parameters;
        this.loader.send(this.sendBody);
        if (!this.options.async && this.loader.overrideMimeType) 
            this.onStateChange();
        } 
        catch (e) { o.onerror();}
    },
    setHeader: function(){
        var o = this.options, self = this;
        var headers = {
            'X-Requested-With': 'XMLHttpRequest',
            'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
         };
        if (o.method == 'POST') {
            headers['Content-type'] = o.contentType + (o.encoding ? '; charset=' + o.encoding : '');
            if (this.loader.overrideMimeType && (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
             headers['Connection'] = 'close';
        }
        for(var key in headers) self.loader.setRequestHeader(key, headers[key]);
    },
    onStateChange: function(){
        var o = this.options, readyState = this.loader.readyState;
        if(readyState == 4){
            var status = this.loader.status || 0;
            var isSuc = (status >= 200&&status < 300)?true:false;
            if(isSuc) this.getResponse.call(this);
            else o.onfailure();
            this.loader.onreadystatechange = function(){};
        }
    },
    getResponse: function(){
        var contentType = this.loader.getResponseHeader('Content-type') || "";
        var dataType = contentType.match(this.type), data = "";
        if(dataType && (dataType = dataType[3])) 
            data = dataType.match(/script/i)?"javascript":(dataType.match(/xml/i)?"xml":"");
        this.options.onsuccess(this.loader, data);
    },
    createQuery: function(){
        var o = this.options.parameters, result = "";
        for(var key in o) result += "&"+key + "=" + o[key];
        result = result.replace(/^&/,"");
        return result;
    }
};